Raspberry Pi 的C++交叉编译环境配置 (2)

上一节我们把RPi的交叉编译器准备好了,但是实际上并没有配置好编译器所需要的库文件。

首先,我们做一些配置,让Ubuntu主机与树莓派通信更加方便。为了方便区分,每段代码的上方用host表示在Ubuntu中执行的命令raspberry表示在树莓派中执行的命令

  1. 添加树莓派的IP到主机的host文件中:

    host

    1
    vi /etc/hosts

    移动光标到相应的地方按 i 进入编辑模式。添加主机的IP地址和名称,然后 :wq 保存

    add_host

  2. 添加公钥到RPi,这样以后对RPi的远程操作不需要重新输入密码了

    host

    1
    ssh-keygen -t rsa

    一路确认不要输入其他参数,成功后会在 ~/.ssh 目录下生成公钥和私钥 id_rsa id_rsa.pub

    将公钥复制到RPi的 ~/.ssh目录下,以后通过Ubuntu主机就可以直接登录RPi不需要重复输入密码了。

    raspberry

    1
    scp ~/.ssh/id_rsa.pub pi@raspberry:~/.ssh/id_rsa.pub

    然后登录到RPi 把id_rsa.pub的内容添加到authorized_keys文件中

    raspberry

    1
    2
    cd .ssh
    cat id_rsa.pub>>authorized_keys

    回到Ubuntu主机的terminal中测试

    host

    1
    ssh pi@raspberry

    如果不需输入密码了说明配置成功了

下一步,我们在Ubuntu上建立一个文件夹用来存放RPi的库和头文件。然后通过rsync命令把树莓派上面的文件拷贝到本地,注意在此之前要上一步的操作已经完成,否则请把rsync命令中的raspberry替换成实际的IP地址。

host

1
2
3
mkdir raspberrypi && cd raspberrypi
mkdir rootfs && cd rootfs
rsync -rl --delete-after --safe-links pi@raspberry:/{lib,usr} $HOME/raspberrypi/rootfs

这里rsync会把RPi上整个 lib 和 usr目录拷贝过来,如果需要Qt库的话可以在拷贝之前先在RPi上配置好Qt开发所需的库然后再拷贝。

拷贝结束后我们写一个测试程序来试一试吧。

用编辑器输入以下代码,保存为 test.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<iostream>
#include<stdio.h>
#include<string>
#include<thread>
using namespace std;
int main( int argc, char* argv[])
{
std::thread t( [](){ puts("Hello, Lambda thread!"); });
string strInfo = "";
cout<<"Hello Test!"<<endl;
float szChara = 8.0;
int sum=0;
for( int i=0; i<10;i++)
{
sum+=i;
}
int size = sizeof(szChara);
cout<< "size of char: "<< size << endl;
t.join();
return 0;
}

在Terminal中用编译器编译一下

host

1
arm-linux-gnueabihf-g++ -Wall -pthread -std=c++11 -o testapp test.cpp -I~/raspberrypi/rootfs/usr/include -L~/raspberrypi/rootfs/lib/arm-linux-gnueabihf

可以看到这时目录中生成了 testapp执行文件,如果此时执行这个文件会提示

bash: ./testapp: cannot execute binary file: Exec format error

这是因为用交叉编译工具编译出来的执行文件是以arm平台作为目标的,而我们的Ubuntu主机是X86架构。可以通过file命令来验证。

compile_run

现在我们把testapp传输到RPi上来执行

raspberry

1
scp testapp pi@raspberry:testapp

切换到RPi的Terminal上来执行

raspberry

1
./testapp

窗口输出

1
2
3
4
pi@raspberrypi:~ $ ./testapp
Hello Test!
size of char: 4
Hello, Lambda thread!

至此,我们对编译环境的配置就完全结束了,下一节我们开始配置VSCODE